package hk.com.fwd.util;

import hk.com.fwd.entity.InputArg;
import hk.com.fwd.entity.TableFiledKeyValue;
import hk.com.fwd.maintest.JDBCSQLSERVERTEST;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.sql.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static hk.com.fwd.maintest.TestGenerator.dbType;

/**
 * Created by lianghm.ext on 2019/10/14.
 */
public class GeneratorUtil {

    public final static String srcPath="C:\\myspringbootcloud\\automatic-generator\\src\\main\\resources\\fileoriginal\\";
    public final static String objPath="C:\\myspringbootcloud\\automatic-generator\\src\\main\\resources\\filetarget\\";

    //hk -fwd
 /*   public final static String mapper_objPath="C:\\dmsHK2\\dms-dao\\src\\main\\resources\\mybatis\\mapper\\";
    public final static String model_objPath="C:\\dmsHK2\\dms-dao\\src\\main\\java\\hk\\com\\fwd\\entity\\";
    public final static String modelDTO_objPath="C:\\dmsHK2\\dms-inf\\src\\main\\java\\hk\\com\\fwd\\model\\";
    public final static String dao_objPath="C:\\dmsHK2\\dms-dao\\src\\main\\java\\hk\\com\\fwd\\dao\\";
    public final static String assembler_objPath="C:\\dmsHK2\\dms-biz\\src\\main\\java\\hk\\com\\fwd\\biz\\assembler\\";
    public final static String bo_objPath="C:\\dmsHK2\\dms-biz\\src\\main\\java\\hk\\com\\fwd\\biz\\";
    public final static String controller_objPath="C:\\dmsHK2\\dms-web\\src\\main\\java\\hk\\com\\fwd\\web\\controller\\";
    public final static String restcontroller_objPath="C:\\dmsHK2\\dms-web\\src\\main\\java\\hk\\com\\fwd\\web\\rest\\";
    public final static String page_objPath="C:\\dmsHK2\\dms-web\\src\\main\\webapp\\WEB-INF\\jsp\\";*/



    public final static String mapper_objPath=objPath;
    public final static String model_objPath=objPath;
    public final static String modelDTO_objPath=objPath;
    public final static String dao_objPath=objPath;
    public final static String assembler_objPath=objPath;
    public final static String bo_objPath=objPath;
    public final static String controller_objPath=objPath;
    public final static String restcontroller_objPath=objPath;
    public final static String page_objPath=objPath;



    public final static String BlankFont="    ";

    public static  void mapper_generator(InputArg inputArg)throws Exception{
        List<TableFiledKeyValue> list=getColumNameFromDb(inputArg.getdBName(),inputArg.getTableName(),inputArg.getRemoveSubStr());
        //list.remove(list.get(0));
        String original="OriginalMapper.xml";
        FileReader reader=new FileReader(srcPath+original);
        BufferedReader br=new BufferedReader(reader);

        String objName=inputArg.getModelName()+".xml";
        FileWriter writer=new FileWriter(mapper_objPath+objName);
        BufferedWriter bw=new BufferedWriter(writer);
        String str;

        String namespace="hk.com.fwd.dao.OriginalDao";
        String modelType="hk.com.fwd.entity.Original";
        String modalName="Original";
        String dbAlias="DB_ALIAS";
        String tableName="TABLE_NAME";
        String insertLocation="(COLUMN_ARRAY_INSERT)";
        String insertLocationProperty="(PROPERTY_ARRAY_INSERT)";
        String findByID="(COLUMN_ID=PROPERTY_ID)";
        String updateLocation="(COLUM=PROPERTY_UPDATE)";


        while ((str=br.readLine())!=null) {
           //result map
            str=str.replace(namespace, inputArg.getPackageName()+".dao."+inputArg.getModelName()+"Dao");
            str=str.replace(modelType, inputArg.getPackageName()+".entity."+inputArg.getModelName());
            str=str.replace(modalName, inputArg.getModelName()).replace(dbAlias,inputArg.getDbAlias()).replace(tableName,inputArg.getTableName());
            str=str.replace(findByID,list.get(0).getColumnName()+" = "+"#{"+list.get(0).getPropertyName()+"}");
            if(str.contains("XXXXXX")){
                //str="";
                for(TableFiledKeyValue it:list){ //竖放
                    String columnProperty=str.replace("XXXXXX",it.getPropertyName()).replace("ZZZZZZ",it.getColumnName());
                    bw.write(columnProperty);
                    bw.write("\r\n");
                }
                str="";
            }


            //insert 横放
            if(str.contains(insertLocation)){
                StringBuilder stringBuilderInsert=new StringBuilder();
                stringBuilderInsert.append("(");
                for(TableFiledKeyValue it:list){
                    stringBuilderInsert.append(it.getColumnName()).append(",");
                }
                stringBuilderInsert.deleteCharAt(stringBuilderInsert.lastIndexOf(","));
                stringBuilderInsert.append(")");
                str=str.replace(insertLocation,stringBuilderInsert.toString());

            }

            //insert
            if(str.contains(insertLocationProperty)){
                StringBuilder stringBuilderInsert=new StringBuilder();
                stringBuilderInsert.append("(");
                for(TableFiledKeyValue it:list){
                    stringBuilderInsert.append("#{").append(it.getPropertyName()).append("},");
                }
                stringBuilderInsert.deleteCharAt(stringBuilderInsert.lastIndexOf(","));
                stringBuilderInsert.append(")");
                str=str.replace(insertLocationProperty,stringBuilderInsert.toString());
            }

            //update  竖放
            if(str.contains(updateLocation)){
                int count =0;
                for(TableFiledKeyValue it:list){
                    count++;
                    String columnProperty="";
                    if(count==list.size()){
                        columnProperty=str.replace(updateLocation,it.getColumnName()+" = "+"#{"+it.getPropertyName()+"}");
                    }else {
                         columnProperty=str.replace(updateLocation,it.getColumnName()+" = "+"#{"+it.getPropertyName()+"}"+",");//把str 的位置格式也copy了
                    }
                    bw.write(columnProperty);
                    bw.write("\r\n");


                }
                str="";
            }

            bw.write(str);
            bw.newLine();
        }
        br.close();
        bw.close();
    }

    public static void model_generator(InputArg inputArg)throws Exception{
        List<TableFiledKeyValue> list=getColumNameFromDb(inputArg.getdBName(),inputArg.getTableName(),inputArg.getRemoveSubStr());
        String original="Original.java";
        FileReader reader=new FileReader(srcPath+original);
        BufferedReader br=new BufferedReader(reader);

        String objName=inputArg.getModelName()+".java";
        FileWriter writer=new FileWriter(model_objPath+objName);
        BufferedWriter bw=new BufferedWriter(writer);
        String str;

        String propertyName="private DATA_TYPE propertyName;";
        String getter="public DATA_TYPE getPropertyName() {return propertyName;}";
        String setter="public void setPropertyName(DATA_TYPE propertyName) {this.propertyName = propertyName;}";


        while ((str=br.readLine())!=null) {

            if(str.contains("Original")){
                str=str.replace("Original",inputArg.getModelName());
            }

            if(str.contains(propertyName)){
                for(TableFiledKeyValue it:list){
                    String PrivateDataTypeProperty=str.replace("DATA_TYPE",it.getDateType()).replace("propertyName",it.getPropertyName());
                    bw.write(PrivateDataTypeProperty);
                    bw.write("\r\n");
                }
                str="";
            }
            if(str.contains(getter)){
                for(TableFiledKeyValue it:list){

                    String GetterProperty=str.replace("DATA_TYPE",it.getDateType()).replace("getPropertyName","get"+upperCase(it.getPropertyName())).replace("return propertyName","return "+it.getPropertyName());

                    bw.write(GetterProperty);
                    bw.write("\r\n");

                    String SetterProperty=setter.replace("DATA_TYPE",it.getDateType()).replace("setPropertyName","set"+upperCase(it.getPropertyName()));
                    Pattern p = Pattern.compile("propertyName");
                    Matcher m = p.matcher(SetterProperty);
                    String tmp = m.replaceAll(it.getPropertyName());
                    bw.write(BlankFont+tmp);
                    bw.write("\r\n");

                }
                str="";
            }
            bw.write(str);
            bw.newLine();
        }
        br.close();
        bw.close();
    }

    public static void modelDTO_generator(InputArg inputArg)throws Exception{
        List<TableFiledKeyValue> list=getColumNameFromDb(inputArg.getdBName(),inputArg.getTableName(),inputArg.getRemoveSubStr());
        String original="OriginalDTO.java";
        FileReader reader=new FileReader(srcPath+original);
        BufferedReader br=new BufferedReader(reader);

        String objName=inputArg.getModelName()+"DTO.java";
        FileWriter writer=new FileWriter(modelDTO_objPath+objName);
        BufferedWriter bw=new BufferedWriter(writer);
        String str;

        String propertyName="private DATA_TYPE propertyName;";
        String getter="public DATA_TYPE getPropertyName() {return propertyName;}";
        String setter="public void setPropertyName(DATA_TYPE propertyName) {this.propertyName = propertyName;}";



        while ((str=br.readLine())!=null) {

            if(str.contains("OriginalDTO")){
                str=str.replace("OriginalDTO",inputArg.getModelName()+"DTO");
            }

            if(str.contains(propertyName)){
                for(TableFiledKeyValue it:list){
                    String PrivateDataTypeProperty=str.replace("DATA_TYPE",it.getDateType()).replace("propertyName",it.getPropertyName());
                    bw.write(PrivateDataTypeProperty);
                    bw.write("\r\n");
                }
                str="";
            }
            if(str.contains(getter)){
                for(TableFiledKeyValue it:list){

                    String GetterProperty=str.replace("DATA_TYPE",it.getDateType()).replace("getPropertyName","get"+upperCase(it.getPropertyName())).replace("return propertyName","return "+it.getPropertyName());

                    bw.write(GetterProperty);
                    bw.write("\r\n");

                    String SetterProperty=setter.replace("DATA_TYPE",it.getDateType()).replace("setPropertyName","set"+upperCase(it.getPropertyName()));
                    Pattern p = Pattern.compile("propertyName");
                    Matcher m = p.matcher(SetterProperty);
                    String tmp = m.replaceAll(it.getPropertyName());
                    bw.write(BlankFont+tmp);
                    bw.write("\r\n");

                }
                str="";
            }
            bw.write(str);
            bw.newLine();
        }
        br.close();
        bw.close();
    }

    public static  void dao_generator(InputArg inputArg)throws Exception{
        String original="OriginalDao.java";
        FileReader reader=new FileReader(srcPath+original);
        BufferedReader br=new BufferedReader(reader);

        String objName=inputArg.getModelName()+"Dao.java";
        FileWriter writer=new FileWriter(dao_objPath+objName);
        BufferedWriter bw=new BufferedWriter(writer);
        String str;

        String packageName="hk.com.fwd";

        while ((str=br.readLine())!=null) {
            //替换文本
            str=str.replace("Original",inputArg.getModelName());
            str=str.replace(packageName,inputArg.getPackageName());

            bw.write(str);
            bw.newLine();
        }
        br.close();
        bw.close();
    }

    public static  void assembler_generator(InputArg inputArg)throws Exception{
        String original="OriginalAssembler.java";
        FileReader reader=new FileReader(srcPath+original);
        BufferedReader br=new BufferedReader(reader);

        String objName=inputArg.getModelName()+"Assembler.java";
        FileWriter writer=new FileWriter(assembler_objPath+objName);
        BufferedWriter bw=new BufferedWriter(writer);
        String str;

        String packageName="hk.com.fwd";
        String OriginalName="Original";

        while ((str=br.readLine())!=null) {
            str=str.replace(packageName,inputArg.getPackageName());
            str=str.replace(OriginalName,inputArg.getModelName());
            bw.write(str);
            bw.newLine();
        }
        br.close();
        bw.close();
    }

    public static  void bo_generator(InputArg inputArg)throws Exception{
        String original="OriginalBo.java";
        FileReader reader=new FileReader(srcPath+original);
        BufferedReader br=new BufferedReader(reader);

        String objName=inputArg.getModelName()+"Bo.java";
        FileWriter writer=new FileWriter(bo_objPath+objName);
        BufferedWriter bw=new BufferedWriter(writer);
        String str;

        String packageName="hk.com.fwd";
        String OriginalName="Original";
        String originalName="original";

        while ((str=br.readLine())!=null) {
            str=str.replace(packageName,inputArg.getPackageName());
            str=str.replace(OriginalName,inputArg.getModelName());
            str=str.replace(originalName,lowerFirstCapse(inputArg.getModelName()));
            bw.write(str);
            bw.newLine();
        }
        br.close();
        bw.close();
    }

    public static  void controller_generator(InputArg inputArg)throws Exception{
        String original="OriginalController.java";
        FileReader reader=new FileReader(srcPath+original);
        BufferedReader br=new BufferedReader(reader);

        String objName=inputArg.getModelName()+"Controller.java";
        FileWriter writer=new FileWriter(controller_objPath+objName);
        BufferedWriter bw=new BufferedWriter(writer);
        String str;

        String packageName="hk.com.fwd";
        String OriginalName="Original";
        String originalName="original";

        String functionId="FUNCTIONID";
        String pageName="PAGENAME";
        String pageDir="PAGEDIR";

        while ((str=br.readLine())!=null) {
            str=str.replace(packageName,inputArg.getPackageName());
            str=str.replace(OriginalName,inputArg.getModelName());
            str=str.replace(originalName,lowerFirstCapse(inputArg.getModelName()));
            str=str.replace(functionId,inputArg.getFunctionId());
            str=str.replace(pageName,inputArg.getPageName());
            str=str.replace(pageDir,inputArg.getPageDir());
            bw.write(str);
            bw.newLine();
        }
        br.close();
        bw.close();
    }

    public static  void restcontroller_generator(InputArg inputArg)throws Exception{
        String original="OriginalRestController.java";
        FileReader reader=new FileReader(srcPath+original);
        BufferedReader br=new BufferedReader(reader);

        String objName=inputArg.getModelName()+"RestController.java";
        FileWriter writer=new FileWriter(restcontroller_objPath+objName);
        BufferedWriter bw=new BufferedWriter(writer);
        String str;

        String packageName="hk.com.fwd";
        String OriginalName="Original";
        String originalName="original";


        while ((str=br.readLine())!=null) {
            str=str.replace(packageName,inputArg.getPackageName());
            str=str.replace(OriginalName,inputArg.getModelName());
            str=str.replace(originalName,lowerFirstCapse(inputArg.getModelName()));

            bw.write(str);
            bw.newLine();
        }
        br.close();
        bw.close();
    }

    public static  void page_generator(InputArg inputArg)throws Exception{
        String original="Original.jsp";
        FileReader reader=new FileReader(srcPath+original);
        BufferedReader br=new BufferedReader(reader);

        String objName=inputArg.getPageName()+".jsp";

        FileWriter writer=new FileWriter(FileUtil.isChartPathExist(page_objPath+inputArg.getPageDir())+"/"+objName);
        BufferedWriter bw=new BufferedWriter(writer);
        String str;

        while ((str=br.readLine())!=null) {
            bw.write(str);
            bw.newLine();
        }
        br.close();
        bw.close();
    }


    public static  void page_generator2(InputArg inputArg)throws Exception{
        String original="ORIGINAL001.html";
        FileReader reader=new FileReader(srcPath+original);
        BufferedReader br=new BufferedReader(reader);

        String objName=inputArg.getPageName()+".html";

        FileWriter writer=new FileWriter(FileUtil.isChartPathExist(page_objPath+inputArg.getPageDir())+"/"+objName);
        BufferedWriter bw=new BufferedWriter(writer);
        String str;

        while ((str=br.readLine())!=null) {
            bw.write(str);
            bw.newLine();
        }
        br.close();
        bw.close();
    }


    /**
     * 首字母转大写
     * @param str
     * @return
     */
    public static  String upperCase(String str) {
        char[] ch = str.toCharArray();
        if (ch[0] >= 'a' && ch[0] <= 'z') {
            ch[0] = (char) (ch[0] - 32);
        }
        return new String(ch);
    }


    /**
     * 首字母转小写
     * @param str
     * @return
     */
    public static String lowerFirstCapse(String str) {
        char[] chars = str.toCharArray();
        chars[0] += 32;
        return String.valueOf(chars);

    }

        /**
         * 获取表结构属性
         * @param dBName
         * @param tableName
         * @return
         */
    public static List<TableFiledKeyValue> getColumNameFromDb(String dBName,String tableName,String removeSubStr){
        List<TableFiledKeyValue> list=new ArrayList<>();
        Connection conn= JDBCSQLSERVERTEST.getConnection(dbType);
        String sql="";
        if(dbType.equals("SQLSERVER")){
            sql="SELECT top 1 * FROM "+dBName+".."+tableName;
        }else if(dbType.equals("MYSQL")){
            sql="SELECT  * FROM "+dBName+"."+tableName+" limit 1";
        }else {}

        PreparedStatement stmt;
        try {
            stmt = conn.prepareStatement(sql);
            ResultSet rs=stmt.executeQuery();
            ResultSetMetaData data=rs.getMetaData();
            while(rs.next()){
                for(int i = 1 ; i<= data.getColumnCount() ; i++){
                    String columnName = data.getColumnName(i);
                    String columnClassName=data.getColumnClassName(i);
                    TableFiledKeyValue tableFiledKeyValue=new TableFiledKeyValue();
                    tableFiledKeyValue.setColumnName(columnName);
                    String propertyName=columnName.replace(removeSubStr,"");
                    tableFiledKeyValue.setPropertyName(getKeyWordAddDownLine(getPropertityName(propertyName,propertyName)));
                    tableFiledKeyValue.setDateType(getdataType(columnClassName));
                    list.add(tableFiledKeyValue);
                }
            }
        } catch (SQLException e) {
            System.out.println(e+"fail to connect the db");
        }
        return list;
    }


    /**
     * 属性 下横线转驼峰
     * @param name
     * @param anotherName
     * @return
     */
    private static String getPropertityName(String name,String  anotherName) {
        name=anotherName;
        //如果最后一个是_ 不做转换
        if(name.indexOf("_")>0&&name.length()!=name.indexOf("_")+1){
            int lengthPlace=name.indexOf("_");
            name=name.replaceFirst("_", "");
            String s=name.substring(lengthPlace, lengthPlace+1);
            s=s.toUpperCase();
            anotherName=name.substring(0,lengthPlace)+s+name.substring(lengthPlace+1);
        }else{
            return  anotherName;
        }
        return getPropertityName(name,anotherName);
    }


    /**
     * 封装数据类简写
     * @param dataType
     * @return
     */
    private static String getdataType(String dataType ){
        String result="";
        switch(dataType){
            case "java.lang.String" :
                result="String";
                break;
            case "java.sql.Date" :
                result="Date";
                break;
            case "java.sql.Timestamp" :
                result="Date";
                break;
            case "java.math.BigDecimal" :
                result="BigDecimal";
                break;
            case "java.lang.Integer" :
                result="Integer";
                break;
            case "java.lang.Long" :
                result="Long";
                break;
             default:result=dataType;

        }
        return result;
    }


    public static String getKeyWordAddDownLine(String propertyName){
        String [] keyWordArray={"abstract","assert","boolean" , "break", "byte", "case", "catch", "char", "class", "const",
        "continue",	"default"	,"do",	"double",	"else",
        "enum",	"extends",	"final"	,"finally"	,"float",
        "for",	"goto"	,"if","implements","import",
        "instanceof","int",	"interface"	,"long"	,"native",
        "new",	"package"	,"private"	,"protected"	,"public",
        "return",	"strictfp","short","static","super",
        "switch",	"synchronized"	,"this"	,"throw"	,"throws",
        "transient","try"	,"void"	,"volatile"	,"while"};
        List<String> keyWordList=new ArrayList<>(Arrays.asList(keyWordArray));
        if (keyWordList.contains(propertyName.toLowerCase())){
            propertyName=propertyName+"_kw";
        }
        return propertyName;
    }










}
